package org.crl.blogsystem.controller;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.json.JSONUtil;
import org.crl.blogsystem.entity.Blog;
import org.crl.blogsystem.entity.Media;
import org.crl.blogsystem.entity.User;
import org.crl.blogsystem.entity.UserFollow;
import org.crl.blogsystem.entity.dto.BlogCreateDTO;
import org.crl.blogsystem.entity.dto.BlogUpdateDTO;
import org.crl.blogsystem.entity.dto.MediaDTO;
import org.crl.blogsystem.message.ResponseMessage;
import org.crl.blogsystem.entity.dto.BlogDTO;
import org.crl.blogsystem.repository.UserFollowRepository;
import org.crl.blogsystem.service.IBlogService;
import org.crl.blogsystem.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;


@RestController
@RequestMapping("/blog")
@CrossOrigin(origins = "http://localhost:3000", allowCredentials = "true", methods = {RequestMethod.GET, RequestMethod.POST, RequestMethod.DELETE, RequestMethod.PUT})
public class BlogController {
    private static final Logger log = LoggerFactory.getLogger(BlogController.class);
    public BlogDTO blogConvert(Blog blog, List<MediaDTO> mediaDTOS) {
        BlogDTO dto = new BlogDTO();
        dto.setId(blog.getId());
        dto.setContent(blog.getContent());
        dto.setCreatedAt(blog.getCreatedAt());
        dto.setLikesCount(blog.getLikesCount());
        dto.setPrivateKey(blog.getPrivateKey());
        dto.setUserId(blog.getUser().getId());
        dto.setUsername(blog.getUser().getUsername());
        dto.setAvatar(blog.getUser().getAvatar());
        dto.setMediaList(mediaDTOS);
        dto.setCommentsCount(blog.getCommentsCount());
        if (StpUtil.isLogin()) {
            Long currentUserId = StpUtil.getLoginIdAsLong();
            dto.setIsMyself(blog.getUser().getId().equals(currentUserId));

            UserFollow userFollow = userFollowRepository.findByFollowerIdAndFollowingId(
                    currentUserId, blog.getUser().getId()
            );
            dto.setIsFollowed(userFollow != null && userFollow.getState() == 1);
        } else {
            dto.setIsMyself(false);
            dto.setIsFollowed(false);
        }
        return dto;
    }

    public MediaDTO mediaConvert(Media media) {
        MediaDTO dto = new MediaDTO();
        dto.setId(media.getId());
        dto.setBlogId(media.getBlog().getId());
        dto.setUrl(media.getUrl());
        return dto;
    }

    @Autowired
    IBlogService blogService;

    @Autowired
    IUserService userService;

    @Autowired
    UserFollowRepository userFollowRepository;

    /**
     ** 添加博客
     *  @param blogJson 博客json
     * @param images 图片
     * @return 博客
     */
    @PostMapping(value = "/create", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public ResponseMessage<BlogDTO> add(
            @RequestPart("blog") String blogJson,
            @RequestPart(name = "images", required = false) List<MultipartFile> images
    ) {
        BlogCreateDTO blogCreateDTO = JSONUtil.toBean(blogJson, BlogCreateDTO.class);
        StpUtil.checkLogin();
        return blogService.createBlog(blogCreateDTO, images);
    }

    /**
     ** 更新博客访问权限
     * @param id 博客id
     * @param blogUpdateDTO 博客更新信息
     * @return 博客
     */
    @PutMapping("/updatePk/{id}")
    public ResponseMessage<BlogDTO> update(@PathVariable("id") Long id, @RequestBody BlogUpdateDTO blogUpdateDTO) {
        StpUtil.checkLogin();
        Long userId = StpUtil.getLoginIdAsLong();
        if(!blogService.getById(id).getUser().getId().equals(userId)) {
            return ResponseMessage.fail("没有权限");
        }
        Blog blog = blogService.update(id, blogUpdateDTO.getPrivateKey());
        return ResponseMessage.success(blogConvert(blog, null));
    }

    /**
     ** 删除博客
     * @param id 博客id
     * @return 删除结果
     */
    @DeleteMapping("/delete/{id}")
    public ResponseMessage<String> delete(@PathVariable("id") Long id) {
        StpUtil.checkLogin();
        Long userId = StpUtil.getLoginIdAsLong();
        if(!blogService.getById(id).getUser().getId().equals(userId)) {
            return ResponseMessage.fail("没有权限");
        }
        blogService.delete(id);
        return ResponseMessage.success("删除成功");
    }

    /**
     ** 获取我的所有博客
     * @return 博客列表
     */
    @GetMapping("/myBlog")
    public ResponseMessage<List<BlogDTO>> getMyBlog(){
        StpUtil.checkLogin();
        List<Blog> blogList = blogService.getByUser();
        List<BlogDTO> blogListDTO = new ArrayList<>();
        for (Blog blog : blogList) {
            List<MediaDTO> mediaDTOS = blog.getMediaList().stream().map(this::mediaConvert).toList();
            blogListDTO.add(blogConvert(blog, mediaDTOS));
        }
        return ResponseMessage.success(blogListDTO);
    }

    /**
     ** 获取用户能见的博客
     * @param userId 用户id
     * @return 博客列表
     */
    @GetMapping("/user/{user_id}")
    public ResponseMessage<List<BlogDTO>> getByUserId(@PathVariable("user_id") Long userId){
        StpUtil.checkLogin();
        List<Blog> blogList = blogService.getByUser(userId);
        List<BlogDTO> blogListDTO = new ArrayList<>();
        for (Blog blog : blogList) {
            List<MediaDTO> mediaDTOS = blog.getMediaList().stream().map(this::mediaConvert).toList();
            blogListDTO.add(blogConvert(blog, mediaDTOS));
        }
        return ResponseMessage.success(blogListDTO);
    }

    /**
     ** 获取用户所有关注者博客
     * @return 博客列表
     */
    @GetMapping("/followersBlog")
    public ResponseMessage<List<BlogDTO>> getFollowersBlog(){
        StpUtil.checkLogin();
        Long userId = StpUtil.getLoginIdAsLong();
        Set<User> following = new HashSet<>(userService.getFollowing(userId)) ;
        List<Blog> blogList = blogService.getByUserSet(following);
        List<BlogDTO> blogListDTO = new ArrayList<>();
        for (Blog blog : blogList) {
            List<MediaDTO> mediaDTOS = blog.getMediaList().stream().map(this::mediaConvert).toList();
            blogListDTO.add(blogConvert(blog, mediaDTOS));
        }
        return ResponseMessage.success(blogListDTO);
    }

    /**
     ** 获取单个博客
     * @param id 博客id
     * @return 博客
     */
    @GetMapping("/getBlog/{id}")
    public ResponseMessage<BlogDTO> getById(@PathVariable("id") Long id){
        StpUtil.checkLogin();
        Blog blog = blogService.getById(id);
        List<MediaDTO> mediaDTOS = blog.getMediaList().stream().map(this::mediaConvert).toList();
        BlogDTO blogDTO = blogConvert(blog, mediaDTOS);
        return ResponseMessage.success(blogDTO);
    }

    /**
     ** 获取热门博客
     * @return 博客列表
     */
    @GetMapping("/hot")
    public ResponseMessage<List<BlogDTO>> getHot(){
        Integer limit = StpUtil.isLogin() ? null : 10;
        List<Blog> blogList = blogService.getHotBlogs(limit);
        List<BlogDTO> blogListDTO = new ArrayList<>();
        for (Blog blog : blogList) {
            List<MediaDTO> mediaDTOS = blog.getMediaList().stream().map(this::mediaConvert).toList();
            blogListDTO.add(blogConvert(blog, mediaDTOS));
        }
        return ResponseMessage.success(blogListDTO);
    }

    /**
     ** 搜索博客
     * @param key 关键字
     * @return 博客列表
     */
    @GetMapping("/search")
    public ResponseMessage<List<BlogDTO>> search(@RequestParam("key") String key){
        StpUtil.checkLogin();
        List<Blog> blogList = blogService.search(key);
        List<BlogDTO> blogListDTO = new ArrayList<>();
        for (Blog blog : blogList) {
            List<MediaDTO> mediaDTOS = blog.getMediaList().stream().map(this::mediaConvert).toList();
            blogListDTO.add(blogConvert(blog, mediaDTOS));
        }        return ResponseMessage.success(blogListDTO);
    }
}
